package com.txby.common.annomapper;

import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.Map.Entry;

import com.txby.common.utils.util.MyBatisReflectUtil;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.ibatis.jdbc.SQL;

/**
 * 动态注解sql
* @ClassName: ProviderTemplate 
* @Description: TODO （描述）
* @author 作者 jacking
* @date 2017-6-16 上午9:23:15 
* @param <T>
 */
public class ProviderTemplate<T> extends MyBatisReflectUtil {
	public String insert(Map<String,Object> map) {
		final T obj=(T) map.get("pojo");
		String sql="";
		caculationColumnList(obj);
		sql= new SQL() {{
		    INSERT_INTO(tablename(obj));
		    VALUES(returnInsertColumnsName(obj), returnInsertColumnsDefine(obj));
		  }}.toString();
		  if(isAutoId()){
			  try {
				BeanUtils.copyProperty(obj, id(obj), getNewId());
			} catch (IllegalAccessException | InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		  }
		  return  sql;
	}
	public String save(Map<String,Object> map) {
		final T obj=(T) map.get("pojo");
		String sql="";
		final String idname = id(obj);
		caculationColumnList(obj);
		sql= new SQL() {
			
			{
			INSERT_INTO(tablename(obj));
			VALUES(returnInsertColumnsName(obj), returnInsertColumnsDefine(obj));
		    }
		 }.toString();
		 
		 sql+=";"+new SQL() { {
					SELECT(returnColumnsDefine(obj));
					FROM(tablename(obj)); 
					WHERE(idname + "='" + getNewId() + "'");
			      }}.toString();
		return  sql;
	}
	
	public String update(Map<String,Object> map) {
		String sql="";
		final T obj=(T) map.get("pojo");
		final String idname = id(obj);
		caculationColumnList(obj);
		 sql= new SQL() {{
			    UPDATE(tablename(obj));
			    SET(returnUpdateSet(obj));
			    WHERE(idname + "=#{pojo." + idname + "}");
			  }}.toString();
	   return sql;
		
	}
	
	public String delete(Map<String,Object> map) {
		final T obj=(T) map.get("pojo");
		String sql="";
		final String idname = id(obj);
		caculationColumnList(obj);
		 sql= new SQL() {{
			    DELETE_FROM(tablename(obj));
			    WHERE(idname + "=#{pojo." + idname + "}");
			  }}.toString();
		return sql;
	}
	
	public String deleteById(final Class clazz,final String id) {
		String sql="";
		final Object obj;
		try {
			obj = clazz.newInstance();
			final String idname = id(obj);
			sql= new SQL() {{
				DELETE_FROM(tablename(obj));
				WHERE(idname + "='" + id + "'");
			}}.toString();
		} catch (InstantiationException | IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return sql;
	}
	
	public String select(Map<String,Object> map) {
		final T obj=(T) map.get("pojo");
		String sql="";
		final String idname = id(obj);
		caculationColumnList(obj);
		 sql= new SQL() {{
		    SELECT(returnInsertColumnsName(obj));
		    FROM(tablename(obj)); 
		    WHERE(idname + "=#{pojo." + idname + "}");
		  }}.toString();
		  return sql;
	}
	
	public String selectAll(Class clazz) {
		String sql="";
		try {
			final Object obj = clazz.newInstance();
			caculationColumnList(obj);
			sql= new SQL() {{
				SELECT(returnColumnsDefine(obj));
				FROM(tablename(obj)); 
			}}.toString();
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		return sql;
	}
	public String countBySql(String countsql) {
		 return countsql;
	}
	public String count(final Class clazz) {
		String sql="";
		try {
			final Object obj = clazz.newInstance();
			final String idname = id(obj);
			sql= new SQL() {{
				SELECT("count(*)");
				FROM(tablename(obj)); 
			}}.toString();
		} catch ( Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}  
		return sql;
	}
	
	public String selectById(final Class clazz,final String id) {
		String sql="";
		try {
			final Object obj = clazz.newInstance();
			final String idname = id(obj);
			caculationColumnList(obj);
			sql= new SQL() {{
				SELECT(returnColumnsDefine(obj));
				FROM(tablename(obj)); 
				WHERE(idname + "='" + id + "'");
			}}.toString();
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		return sql;
	}
	public String selectByProperty(final Class clazz,final Map<String,Object> param,final boolean isAndOr) {
		String sql="";
		try {
			final Object obj = clazz.newInstance();
			caculationColumnList(obj);
			sql= new SQL() {{
				SELECT(returnColumnsDefine(obj));
				FROM(tablename(obj)); 
				String whereSql="";
				int index=0;
				String flagJoin="  and  ";
				flagJoin=!isAndOr?" or ":flagJoin;
				for(Entry<String, Object> entry:param.entrySet()){
					index++;
					whereSql+=entry.getKey() + "=#{pojo." + entry.getKey() + "} ";
					whereSql=index<param.size()?whereSql+flagJoin:whereSql;
				}
				if(!whereSql.equals("")){
					WHERE(whereSql);
				}
			}}.toString();
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		return sql;
	}
	public String selectLikeByProperty(final Class clazz,final Map<String,Object> param,final boolean isAndOr) {
		String sql="";
		try {
			final Object obj = clazz.newInstance();
			caculationColumnList(obj);
			sql= new SQL() {{
				SELECT(returnColumnsDefine(obj));
				FROM(tablename(obj)); 
				String whereSql="";
				int index=0;
				String flagJoin="  and  ";
				flagJoin=!isAndOr?" or ":flagJoin;
				for(Entry<String, Object> entry:param.entrySet()){
					index++;
					whereSql+=entry.getKey() + " like #{pojo." + entry.getKey() + "} ";
					whereSql=index<param.size()?whereSql+flagJoin:whereSql;
				}
				if(!whereSql.equals("")){
					WHERE(whereSql);
				}
			}}.toString();
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		return sql;
	}
	
}
